package com.xdcplus.web.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.xdcplus.core.exceptions.XdcRuntimeException;
import com.xdcplus.etl.schedule.exceptions.EtlScheduleException;
import com.xdcplus.mom.constants.NumberConstant;
import com.xdcplus.web.common.constants.DwWorkConfConstants;
import com.xdcplus.web.common.pojo.entity.DwWorkConf;
import com.xdcplus.web.service.DwWorkConfService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.time.LocalDateTime;

/**
 * @author Qing.Ma
 * @since 2023/7/6
 */
@Slf4j
@Service
public abstract class AbstractJobHandler implements AbstractJobHandlerI {

    @Autowired
    private DwWorkConfService dwWorkConfService;

    protected DwWorkConf beginJob(String etlName) {

        log.info("handler:{} 执行开始!", etlName);

        LocalDateTime endDateTime = LocalDateTime.now().minusMinutes(10);
        LocalDateTime startDateTime = endDateTime.minusMinutes(5);

        DwWorkConf dwWorkConf = dwWorkConfService.queryDwWorkConfByEtlName(etlName);
        if (ObjectUtil.isNull(dwWorkConf)) {
            throw new XdcRuntimeException("任务不存在");
        }

        if (DwWorkConfConstants.ERROR.equals(dwWorkConf.getEtlRunFlg())) {
            throw new EtlScheduleException("任务异常已暂停");
        }

        if (DwWorkConfConstants.RUN.equals(dwWorkConf.getEtlRunFlg())) {
            throw new XdcRuntimeException("任务正在执行中...");
        }

        if (dwWorkConf.getEtlQueryMinute() < NumberConstant.ZERO) {
            throw new XdcRuntimeException("任务执行范围不能小于0");
        }

        if (dwWorkConf.getEtlQueryMinute() > NumberConstant.ZERO && dwWorkConf.getEtlStartTimestamp() == null) {
            throw new XdcRuntimeException("任务增量抽取必须设定执行开始时间");
        }
        dwWorkConf.setEtlStartTimestamp(Timestamp.valueOf(startDateTime));
        dwWorkConf.setEtlEndTimestamp(Timestamp.valueOf(endDateTime));
        dwWorkConf.setEtlRunFlg(DwWorkConfConstants.RUN);
        dwWorkConf.setUpdatedTime(new Timestamp(DateUtil.current()));
        dwWorkConfService.updateById(dwWorkConf);
        return dwWorkConf;
    }

    protected void endJob(DwWorkConf dwWorkConf) {
        if (ObjectUtil.isNull(dwWorkConf)) {
            throw new XdcRuntimeException("任务不存在");
        }
        dwWorkConf.setEtlRunFlg(DwWorkConfConstants.READY);
        dwWorkConf.setEtlStartTimestamp(
                Timestamp.valueOf(
                        dwWorkConf.getEtlStartTimestamp()
                                .toLocalDateTime().plusMinutes(dwWorkConf.getEtlQueryMinute())
                )
        );
        dwWorkConf.setEtlEndTimestamp(
                Timestamp.valueOf(
                        dwWorkConf.getEtlEndTimestamp()
                                .toLocalDateTime().plusMinutes(dwWorkConf.getEtlQueryMinute())
                )
        );
        dwWorkConf.setEndTimestamp(new Timestamp(DateUtil.current()));
        dwWorkConf.setFinalTimestamp(new Timestamp(DateUtil.current()));
        dwWorkConfService.updateById(dwWorkConf);
    }

    protected void runJob(DwWorkConf dwWorkConf) {
        if (ObjectUtil.isNull(dwWorkConf)) {
            throw new XdcRuntimeException("任务不存在");
        }
        dwWorkConf.setEtlRunFlg(DwWorkConfConstants.RUN);
        dwWorkConf.setEtlStartTimestamp(
                Timestamp.valueOf(
                        dwWorkConf.getEtlStartTimestamp()
                                .toLocalDateTime().plusMinutes(dwWorkConf.getEtlQueryMinute())
                )
        );
        dwWorkConf.setEtlEndTimestamp(
                Timestamp.valueOf(
                        dwWorkConf.getEtlEndTimestamp()
                                .toLocalDateTime().plusMinutes(dwWorkConf.getEtlQueryMinute())
                )
        );
        dwWorkConf.setEndTimestamp(new Timestamp(DateUtil.current()));
        dwWorkConf.setFinalTimestamp(new Timestamp(DateUtil.current()));
        dwWorkConfService.updateById(dwWorkConf);
    }

    protected void stopJob(DwWorkConf dwWorkConf) {
        if (ObjectUtil.isNull(dwWorkConf)) {
            throw new XdcRuntimeException("任务不存在");
        }
        dwWorkConf.setEtlRunFlg(DwWorkConfConstants.ERROR);
        dwWorkConf.setEndTimestamp(new Timestamp(DateUtil.current()));
        dwWorkConf.setFinalTimestamp(new Timestamp(DateUtil.current()));
        dwWorkConfService.updateById(dwWorkConf);
    }

    protected void log(DwWorkConf conf, Object o) {
        log.info("handler:{} 执行成功! 返回:{}", conf.getEtlName(), JSON.toJSON(o));
    }
}
